package wangjg.commons.dao;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import wangjg.commons.bean.BeanUtil;

/**
 * 
 * @author wangjg
 *
 */
public class ResultMapping {

	public static <T> List<T> getObjectList(ResultSet rs, Class<T> cls) throws Exception{
		List<String> ppList = new ArrayList<String>();
		ResultSetMetaData rsm = rs.getMetaData();
		for(int i=1; i<=rsm.getColumnCount(); i++){
			String columnName = rsm.getColumnName(i);
			ppList.add(columnName);
		}

		List<T> objList = new ArrayList<T>();
		while(rs.next()){
			T obj = cls.newInstance();
			for(String name:ppList){
				BeanUtil.setNestedProperty(obj, name, rs.getObject(name));	
			}
			objList.add(obj);
		}
		return objList;
	}
	
	/**
	 * 取两列
	 * @param rs
	 * @param keyName
	 * @param valueName
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public static <K,V> Map<K,V> getPropertyMap(ResultSet rs, String keyName, String valueName) throws SQLException{
		Map<K,V> map = new HashMap<K,V>();
		while(rs.next()){
			K key = (K) rs.getObject(keyName);
			V value = (V) rs.getObject(valueName);
			map.put(key, value);
		}
		return map;
	}
	
	/**
	 * 取一列
	 * @param rs
	 * @param valueName
	 * @return
	 * @throws SQLException
	 */
	@SuppressWarnings("unchecked")
	public static <T> List<T> getPropertyList(ResultSet rs, String valueName) throws SQLException{
		List<T> list = new ArrayList<T>();
		while(rs.next()){
			T value = (T) rs.getObject(valueName);
			list.add(value);
		}
		return list;
	}
	
	public static List<String> getColumnNames(ResultSet rs) throws SQLException{
		List<String> ppList = new ArrayList<String>();
		ResultSetMetaData rsm = rs.getMetaData();
		for(int i=1; i<=rsm.getColumnCount(); i++){
			String columnName = rsm.getColumnName(i);
//			columnName = columnName.toUpperCase();
			ppList.add(columnName);
		}
		return ppList;
	}
	
	public static List<ColumnInfo> getColumnInfo(ResultSet rs) throws SQLException{
		List<ColumnInfo> list = new ArrayList<ColumnInfo>();
		ResultSetMetaData rsm = rs.getMetaData();
		for(int i=1; i<=rsm.getColumnCount(); i++){
			ColumnInfo ci = new ColumnInfo();
			ci.setAuto(rsm.isAutoIncrement(i));
			ci.setName(rsm.getColumnName(i));
			ci.setType(rsm.getColumnTypeName(i));
			ci.setLength(rsm.getPrecision(i));
			ci.setNullable(rsm.isNullable(i)!=ResultSetMetaData.columnNoNulls);
			list.add(ci);
		}
		return list;
	}
	
	public static List<Map<String,Object>> getMapList(ResultSet rs) throws SQLException{
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		while(rs.next()){
			Map<String,Object> map = new LinkedHashMap<String,Object>();
			ResultSetMetaData rsm = rs.getMetaData();
			for(int i=1;i<=rsm.getColumnCount();i++){
				String columnName = rsm.getColumnName(i);
				columnName = columnName.toUpperCase();
				Object columnValue = rs.getObject(i);
				map.put(columnName, columnValue);
			}
			list.add(map);
		}
		return list;
	}
	
	public static class ColumnInfo{
		private Boolean auto;
		private String name;
		private String type;
		private Integer length;
		private Boolean nullable;
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public Integer getLength() {
			return length;
		}
		public void setLength(Integer length) {
			this.length = length;
		}
		public Boolean getNullable() {
			return nullable;
		}
		public void setNullable(Boolean nullable) {
			this.nullable = nullable;
		}
		public Boolean getAuto() {
			return auto;
		}
		public void setAuto(Boolean auto) {
			this.auto = auto;
		}
		
		@Override
		public String toString() {
			return "ColumnInfo [auto=" + auto + ", name=" + name + ", type="
					+ type + ", length=" + length + ", nullable=" + nullable
					+ "]";
		}

	}
}
